require "View/MainUI/CityPlayer"
---@class CityPlayerMgr
CityPlayerMgr = {
    ---@type CityPlayer
    pickUpPlayer = nil,
    HeroLocaltionPosRatio = {{1,10},{11,20},{21,40},{41,80},{81,100}},
    HeroLocaltionPos = { 880, 1450, 2400, 3500, 4300 },   -- 小人移动定位
    POS_Y_MIN = 1400,   --人物移动定位范围
    POS_Y_MAX = 1765,   --人物移动定位范围
    POS_X_MIN = 260,
    POS_X_MAX = 4380,
    ---@type CityPlayer[]
    playerList = {},
    buildTime = 0,
    isDirty = false,
    mainPlayer = nil
}
local this = CityPlayerMgr

CityPlayerMgr.LoadState = {
    None = 0,
    LoadingPlayer = 1,
    LoadPlayerDone = 2,
    LoadingPet = 3,
    LoadComplete = 4,
}

function CityPlayerMgr.Create(playerRoot)
    if not this.uICityRunAI then
        ---@type UICityRunAIManager
        this.uICityRunAI = UICityRunAIManager.New(this.HeroLocaltionPos)
    end
    this.uICityRunAI:Run()
    this.playerRoot = playerRoot
    this.screenRateX = 1080 / UnityEngine.Screen.width;
    this.screenRateY = 1920 / UnityEngine.Screen.height;
end
function CityPlayerMgr.DestroyAllPlayerModel()
    if this.uICityRunAI ~= nil then
        this.uICityRunAI:Destroy()
        this.uICityRunAI = nil
    end
    for k,v in pairs(this.playerList) do
        v:Destroy()
        --this.playerList[k] = nil
    end
    this.isDirty = true
end
function CityPlayerMgr.AddPlayer(msg)
    local roleId = tostring(msg.roleId)

    local player = this.playerList[roleId]
    local count = table.getn(this.playerList)
    if not player then
        if count > 15 then return end
        player = CityPlayer.New()
    end
    player:UpdateInfoMsg(msg)
    this.playerList[roleId] = player
    this.isDirty = true
end
function CityPlayerMgr.AddMainPlayer(MainChrSpine)
    this.mainPlayer = MainChrSpine
end
function CityPlayerMgr.DestroyPlayer(id)

    local player = this.playerList[id]
    if not player then return end
    if this.uICityRunAI then
        this.uICityRunAI:RemoveObj(player.ModelSpine)
    end
    player:Destroy()
    this.playerList[id] = nil
end
function CityPlayerMgr.OnDestroy()
    this.DestroyAllPlayerModel()
    table.clear(this.playerList)
end
function CityPlayerMgr.ChangePlayerPet(playerId,genes)
    local player = this.playerList[playerId]
    if not player then return end
    player:ChangePetInfo(genes)
    this.isDirty = true
end
function CityPlayerMgr.SortPlayerOrder(jornIdle,jornMove,title)
    local minIndex = -1
    local cacheOtherCityPlayer = {}
    local transToFGUIComList = {}
    for key, player in pairs(this.playerList) do
        if player.ModelSpine then
            local index = player.ModelSpine.parent:GetChildIndex(player.ModelSpine)
            if minIndex == -1 or index < minIndex then
                minIndex = index
            end
            table.insert(cacheOtherCityPlayer,player.CharObjAniTrans)
            transToFGUIComList[player.CharObjAniTrans] = player.ModelSpine
        end
    end
    --主角
    local main = this.mainPlayer
    if main and main.obj then
        table.insert(cacheOtherCityPlayer,main.animaObj.transform)
        transToFGUIComList[main.animaObj.transform] = main.obj
        local index = main.obj.parent:GetChildIndex(main.obj)
        if minIndex == -1 or index < minIndex then
            minIndex = index
        end
    end
    --[[if main and main.ModelSpine then
        table.insert(cacheOtherCityPlayer,main.CharObjAniTrans)
        transToFGUIComList[main.CharObjAniTrans] = main.ModelSpine
        local index = main.ModelSpine.parent:GetChildIndex(main.ModelSpine)
        if minIndex == -1 or index < minIndex then
            minIndex = index
        end
    end]]
    minIndex = 92
    table.sort(cacheOtherCityPlayer,function(a,b)
        return a.position.y > b.position.y
    end)
    for index, value in ipairs(cacheOtherCityPlayer) do
        local com = transToFGUIComList[value]
        com.parent:SetChildIndex(com,minIndex + index - 3)
    end
    if jornMove and jornIdle then
        if minIndex > 3 then
            jornIdle.parent:SetChildIndex(jornIdle,minIndex+1)
            jornMove.parent:SetChildIndex(jornMove,minIndex+1)
            title.parent:SetChildIndex(title,minIndex+1)
        end
        for k,v in ipairs(cacheOtherCityPlayer) do
            local com = transToFGUIComList[v]
            local index = com.parent:GetChildIndex(com)-1
            if com.y >= jornIdle.y then
                jornIdle.parent:SetChildIndex(jornIdle,index)
                jornMove.parent:SetChildIndex(jornMove,index)
                title.parent:SetChildIndex(title,index)
            end
        end
    end
end

function CityPlayerMgr.AddAI(obj,animNames,petModel)
    this.uICityRunAI:AddObj(obj,animNames,petModel)
end
function CityPlayerMgr.RemoveAi(obj)
    this.uICityRunAI:RemoveObj(obj)
end
function CityPlayerMgr.Update()
    if  this.isDirty then
        this.buildTime = this.buildTime + 1
        if this.buildTime < 20 then
            return
        end
        this.buildTime = 0
        local flag = false
        for k,v in pairs(this.playerList) do
            if v:Load(this.playerRoot) then
                flag = true
                break
            end
        end
        if not flag then
            this.isDirty = false
        end
    end
    local player = this.pickUpPlayer
    if (player ~= nil and player.ModelSpine ~= nil) then
        local PickX = (Input.mousePosition.x - this.lastMouseX) * this.screenRateX
        local PickY = (Input.mousePosition.y - this.lastMouseY) * this.screenRateY
        local x = player.ModelSpine.x + PickX
        local y = player.ModelSpine.y - PickY
        if player.orY - y > 30 then
            this.lastMouseX = Input.mousePosition.x;
            this.lastMouseY = Input.mousePosition.y;
            player.ModelSpine:SetXY(x, y)
        end
    end

end



function CityPlayerMgr.SetPickUpPlayer(player)
    this.pickUpPlayer = player
end
function CityPlayerMgr.GetPickUpPlayer()
    return this.pickUpPlayer
end
function CityPlayerMgr.HasPickUpPlayer()
    return this.pickUpPlayer ~= nil
end
function CityPlayerMgr.getAnimationName(AniTab, aniName)
    local str = G.dataTable["t_roleconfig"][AniTab][aniName][1];
    local randomNames = string.split(str, ",");
    return randomNames[math.random(1, #randomNames)];
end
---@param player CityPlayer
function CityPlayerMgr.StartPickUp(player)
    this.pickUpPlayer = player
    this.uICityRunAI:TempStopAI(player.ModelSpine)
    Util.PlayAction(this.pickUpPlayer.animObj, this.getAnimationName(player.modlename, "run"), true, 0.5);
    player.CharObjShadow:SetActive(false)
    this.lastMouseX = Input.mousePosition.x
    this.lastMouseY = Input.mousePosition.y
end
function CityPlayerMgr.EndPickUp()
    local player = this.pickUpPlayer
    if not player then return end
    player.ModelSpine:TweenMoveY(player.orY,0.39):SetEase(EaseType.Linear):OnComplete(this.EndPickUpComplete)
    --player.ModelSpine.displayObject.gameObject.transform:DOLocalMoveY(-player.orY, 0.39,false):OnComplete(this.EndPickUpComplete);
end
function CityPlayerMgr.EndPickUpComplete()
    local player = this.pickUpPlayer
    if player == nil then return end
    Util.PlayAction(player.animObj, this.getAnimationName(player.modlename, "idleFree"));
    this.uICityRunAI:TempRunAI(player.ModelSpine)
    player.CharObjShadow:SetActive(true)
    -- 同步一下
    --local _,posy = Util.Lua_GetLocalPositionXYZ(player.ModelSpine.displayObject.gameObject,0,0,0);
    --player.ModelSpine.y = -posy

    this.pickUpPlayer = nil
end
function CityPlayerMgr.CreateTestPlayer()
    local msgdata = logicMgr.ChatManager.GetLastChatMsg(Config.MsgChannel.World)
    if msgdata then
        msgdata = clone(msgdata)
        msgdata.roleId = tostring(math.random(1,10000))
        msgdata.headPic = logicMgr.HeroManager.GetRoleInfo("pic")
        logicMgr.CityPlayerMgr.AddPlayer(msgdata)
    end
end
return CityPlayerMgr